﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FinanSoft.BusinessLayer;
using FinanSoft.Entities;
using FinanSoft.Utilities;

namespace FinanSoft
{
    public partial class frmCrearCuenta : Form
    {

        int[] _currencyIds;
        List<int> _accountIds;
        int _editedAccountId;

        public frmCrearCuenta(int editedAccountId)
        {
            InitializeComponent();
            _editedAccountId = editedAccountId;
            fillFields();
        }

        private void changeSystemCode(object sender, EventArgs e)
        {
            txtCodSystem.Text = CatalogManager.GetInstance().GetAccount(_accountIds[cmbCtaPadre.SelectedIndex]).AccountCode.Substring(0, 1);
        }

        private void fillFields()
        {
            fillCurrencies();
            txtCodSystem.Enabled = false;
            if (_editedAccountId != Constants.INVALID_ID)
            {
                Account editedAccount = CatalogManager.GetInstance().GetAccount(_editedAccountId);
                if (editedAccount.Parent != null)
                {
                    cmbCtaPadre.Items.Add(editedAccount.Parent.DisplayName);
                    cmbCtaPadre.SelectedIndex = 0;
                }
                else
                    textNombre.Enabled = false;
                cmbCtaPadre.Enabled = false;
                txtCodSystem.Text = editedAccount.AccountCode.Substring(0, 1);
                txtCodUser.Text = editedAccount.AccountCode.Substring(1);
                txtCodUser.Enabled = false;
                textNombre.Text = editedAccount.Name;
                txtNombreExt.Text = editedAccount.ForeignName;

                if (editedAccount.IsTitle)
                    radTitulo.Select();
                else
                    radCuenta.Select();
                radTitulo.Enabled = false;
                radCuenta.Enabled = false;
            }
            else
            {
                cmbCtaPadre.SelectedIndexChanged +=new EventHandler(this.changeSystemCode);
                radTitulo.Select();
                fillParents();
            }
        }

        private void fillParents()
        {
            _accountIds = new List<int>();
            AccountingCatalog catalog = CatalogManager.GetInstance().GetAccountingCatalog();
            foreach (Account account in catalog.PrincipalAccounts)
                addAccount(account, 0);
            cmbCtaPadre.SelectedIndex = 0;
        }

        private void addAccount(Account account, int level)
        {
            if (account.IsTitle)
            {
                _accountIds.Add(account.AccountID);
                cmbCtaPadre.Items.Add(FormUtilities.AddTabs(account.DisplayName, level));
                foreach (Account child in account.Children.Values)
                    addAccount(child, level + 1);
            }
        }

        private bool isEditedCurrency(int currencyId)
        {
            return _editedAccountId != Constants.INVALID_ID && currencyId == CatalogManager.GetInstance().GetAccount(_editedAccountId).AccountCurrency.Id;
        }

        private void fillCurrencies()
        {
            int selectedId = Constants.INVALID_ID;
            List<Currency> addedCurrencies = MoneyManager.GetInstance().GetAddedCurrencies();
            _currencyIds = new int[addedCurrencies.Count+2];
            for(int currencyIndex = 0; currencyIndex < addedCurrencies.Count; currencyIndex++)
            {
                _currencyIds[currencyIndex] = addedCurrencies[currencyIndex].Id;
                cmbMoneda.Items.Add(addedCurrencies[currencyIndex].Name);
                if (isEditedCurrency(addedCurrencies[currencyIndex].Id))
                    selectedId = currencyIndex;
            }
            Currency sys = MoneyManager.GetInstance().SystemCurrency;
            _currencyIds[_currencyIds.Length-2] = sys.Id;
            cmbMoneda.Items.Add(sys.Name);
            if (isEditedCurrency(sys.Id))
                selectedId = _currencyIds.Length - 2;
            Currency local = MoneyManager.GetInstance().LocalCurrency;
            _currencyIds[_currencyIds.Length-1] = local.Id;
            cmbMoneda.Items.Add(local.Name);
            if(selectedId != Constants.INVALID_ID)
                cmbMoneda.SelectedIndex = selectedId;
            else
                cmbMoneda.SelectedIndex = cmbMoneda.Items.Count - 1;
        }

        private void createAccount()
        {
            if (validateCreateFields())
            {
                Account newAccount = new Account();
                newAccount.AccountCurrency = MoneyManager.GetInstance().GetCurrency(_currencyIds[cmbMoneda.SelectedIndex]);
                newAccount.Name = textNombre.Text;
                newAccount.ForeignName = txtNombreExt.Text;
                newAccount.AccountCode = txtCodSystem.Text + txtCodUser.Text;
                newAccount.Parent = CatalogManager.GetInstance().GetAccount(_accountIds[cmbCtaPadre.SelectedIndex]);
                newAccount.IsTitle = radTitulo.Checked;
                CatalogManager.GetInstance().CreateNewAccount(newAccount, newAccount.Parent.AccountID);
                if (CatalogManager.GetInstance().IsError)
                    MessageBox.Show(CatalogManager.GetInstance().ErrorMessage, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                    MessageBox.Show(MessageConstants.ACCOUNT_INSERTED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
        }

        private void editAccount()
        {
            if(validateUpdateFields())
            {
                Account newAccount = new Account();
                newAccount.AccountID = _editedAccountId;
                newAccount.AccountCurrency = MoneyManager.GetInstance().GetCurrency(_currencyIds[cmbMoneda.SelectedIndex]);
                newAccount.Name = textNombre.Text;
                newAccount.ForeignName = txtNombreExt.Text;
                CatalogManager.GetInstance().ModifyAccount(newAccount);
                if (CatalogManager.GetInstance().IsError)
                    MessageBox.Show(CatalogManager.GetInstance().ErrorMessage, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                    MessageBox.Show(MessageConstants.ACCOUNT_UPDATED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
        }

        private bool validateUpdateFields()
        {
            if (textNombre.Text.Trim().Length == 0 || txtNombreExt.Text.Trim().Length == 0)
            {
                MessageBox.Show(MessageConstants.MISSING_FIELDS, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            else
                return true;
        }

        private bool validateCreateFields()
        {
            if (txtCodUser.Text.Trim().Length == 0)
            {
                MessageBox.Show(MessageConstants.MISSING_FIELDS, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            else if (txtCodUser.Text.Length > Constants.MAX_ACCOUNT_CODE_CHAR - 1)
            {
                MessageBox.Show(MessageConstants.ACCOUNT_CODE_MUST_BE_15, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            else
                return validateUpdateFields();
        }

        private void btnCerrar_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnGuardar_Click(object sender, EventArgs e)
        {
            if (_editedAccountId == Constants.INVALID_ID)
            {
                createAccount();
                this.Close();
            }
            else
            {
                editAccount();
                this.Close();
            }
        }
    }
}
